import { Editor as CoreEditor } from '@tiptap/core'
import Document from '@tiptap/extension-document'
import Highlight from '@tiptap/extension-highlight'
import Typography from '@tiptap/extension-typography'
import StarterKit from '@tiptap/starter-kit'
import Placeholder from '@tiptap/extension-placeholder'
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import Table from '@tiptap/extension-table'
import TableCell from '@tiptap/extension-table-cell'
import TableHeader from '@tiptap/extension-table-header'
import TableRow from '@tiptap/extension-table-row'
// import Dropcursor from '@tiptap/extension-dropcursor'
import FileHandler from '@tiptap-pro/extension-file-handler'
import Image from '@tiptap/extension-image'
// import Text from '@tiptap/extension-text'
import TextAlign from '@tiptap/extension-text-align'
import Underline from '@tiptap/extension-underline'
import TaskItem from '@tiptap/extension-task-item'
import TaskList from '@tiptap/extension-task-list'
import CharacterCount from '@tiptap/extension-character-count'
import Link from '@tiptap/extension-link'
import { TableOfContents } from '@tiptap-pro/extension-table-of-contents'
import Color from '@tiptap/extension-color'
import TextStyle from '@tiptap/extension-text-style'
import FontFamily from '@tiptap/extension-font-family'

import Commands from './commands'
import suggestion from './suggestion'
import { Operation } from './operation'
import EditorOptions from '../types/editorOptions'
import AiWrite from './ai/aiWrite'
import { uploadFile as defaultUploadFile } from '../utils/upload'

import '@/styles/index.scss'
import 'tippy.js/dist/tippy.css'
import 'tippy.js/themes/light.css'
import '@/assets/iconfont/remixicon.css'

import { createLowlight } from 'lowlight'
import css from 'highlight.js/lib/languages/css'
import js from 'highlight.js/lib/languages/javascript'
import ts from 'highlight.js/lib/languages/typescript'
import html from 'highlight.js/lib/languages/xml'
const lowlightInstance = createLowlight()
lowlightInstance.register({ html, css, js, ts })
import defaultAiModel from './ai/AiModel'
import Message from '../types/message'
import defaultMessage from '../utils/message'
class Editor extends CoreEditor {
  public message: Message;
  constructor(options: EditorOptions) {
    const { message = defaultMessage, placeholder, onUpdateAnchors, uploadFile = defaultUploadFile, AiModel=defaultAiModel,  onSave, onExport, onShare, extensions = [], editorProps = {
      attributes: {
        class: 'progress-editor prose',
      },
    } } = options;
    let defaultExtensions = [
      Document,
      StarterKit.configure({
        document: false
      }),
      Highlight,
      Typography,
      TextAlign.configure({
        types: ['heading', 'paragraph'],
      }),
      TextStyle,
      FontFamily,
      Color,
      Underline,
      Link.configure({
        openOnClick: true,
        defaultProtocol: 'https',
      }),
      TaskList,
      TaskItem.configure({
        nested: true,
      }),
      CodeBlockLowlight.configure({
        lowlight: lowlightInstance,
      }),
      TableOfContents.configure({
        onUpdate: (content) => {
          onUpdateAnchors && onUpdateAnchors(content)
        }
      }),
      Placeholder.configure({
        emptyEditorClass: 'is-editor-empty',
        placeholder: placeholder
      }),
      Image.configure({
        inline: true,
        allowBase64: true
      }),
      FileHandler.configure({
        allowedMimeTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
        onDrop: (currentEditor, files, pos) => {
          files.forEach(async file => {
            let src = await (currentEditor as Editor).uploadFile(file);
            currentEditor.chain().insertContentAt(pos, {
              type: 'image',
              attrs: { src }
            }).focus().run()
          })
        },
        onPaste: (currentEditor, files, htmlContent) => {
          files.forEach(async file => {
            if (htmlContent) {
              // if there is htmlContent, stop manual insertion & let other extensions handle insertion via inputRule
              // you could extract the pasted file from this url string and upload it to a server for example
              console.log(htmlContent) // eslint-disable-line no-console
              return false
            }
            let src = await (currentEditor as Editor).uploadFile(file);
            currentEditor.chain().insertContentAt(currentEditor.state.selection.anchor, {
              type: 'image',
              attrs: { src }
            }).focus().run()
          })
        }
      }),
      Commands.configure({
        suggestion,
      }),
      Table.configure({
        resizable: true,
      }),
      TableRow,
      TableHeader,
      TableCell,
      CharacterCount,
      Operation.configure({
        onSave,
        onExport,
        onShare
      }),
      AiWrite
    ]
    options.extensions = [...defaultExtensions, ...extensions];
    options.editorProps = editorProps;
    options.uploadFile = uploadFile;
    options.AiModel = AiModel;
    super(options);
    this.message = message;
  }
  public chat(question: string, prompt: string, onMessage: (msg: string) => void, onEnd: () => void) {
    return (this.options as EditorOptions).AiModel.chat(question, prompt, onMessage, onEnd);
  }
  public uploadFile(file: File) {
    return (this.options as EditorOptions)?.uploadFile(file);
  }
  public setOptions(options: EditorOptions) {
    super.setOptions(options);
    if (options.message) {
      this.message = options.message;
    }
  }
}


export default Editor;